<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>进程管理控制台</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.2/font/bootstrap-icons.css" rel="stylesheet">
    <style>
        :root {
            --primary-color: #4a90e2;
            --success-color: #28a745;
            --danger-color: #dc3545;
            --warning-color: #ffc107;
            --dark-color: #343a40;
        }

        body {
            background-color: #f8f9fa;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        }

        .container-fluid {
            padding: 20px;
        }

        .card {
            border: none;
            border-radius: 10px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
            margin-bottom: 20px;
            height: 100%;
        }

        .card-header {
            background-color: white;
            border-bottom: 1px solid #eee;
            padding: 15px 20px;
        }

        .process-card {
            transition: transform 0.2s;
        }

        .process-card:hover {
            transform: translateY(-2px);
        }

        .status-running {
            color: var(--success-color);
        }

        .status-stopped {
            color: var(--danger-color);
        }

        .monitored-processes {
            height: calc(100vh - 100px);
            overflow-y: auto;
        }

        .monitored-processes::-webkit-scrollbar {
            width: 6px;
        }

        .monitored-processes::-webkit-scrollbar-track {
            background: #f1f1f1;
            border-radius: 3px;
        }

        .monitored-processes::-webkit-scrollbar-thumb {
            background: #888;
            border-radius: 3px;
        }

        .monitored-processes::-webkit-scrollbar-thumb:hover {
            background: #555;
        }

        .btn {
            border-radius: 5px;
            padding: 8px 16px;
            font-weight: 500;
        }

        .btn-primary {
            background-color: var(--primary-color);
            border-color: var(--primary-color);
        }

        .btn-danger {
            background-color: var(--danger-color);
            border-color: var(--danger-color);
        }

        .stats-card {
            background: linear-gradient(45deg, var(--primary-color), #6aa8ff);
            color: white;
        }

        .stats-card .card-body {
            padding: 20px;
        }

        .stats-card h3 {
            font-size: 2rem;
            margin-bottom: 0;
        }

        .stats-card p {
            margin-bottom: 0;
            opacity: 0.8;
        }

        .badge {
            padding: 5px 10px;
            border-radius: 15px;
        }

        .progress {
            height: 8px;
            border-radius: 4px;
        }

        .file-input-wrapper {
            position: relative;
            overflow: hidden;
            display: inline-block;
        }

        .file-input-wrapper input[type=file] {
            position: absolute;
            left: 0;
            top: 0;
            opacity: 0;
            cursor: pointer;
        }

        .file-input-trigger {
            display: inline-block;
            padding: 8px 16px;
            background: #f8f9fa;
            border: 1px solid #dee2e6;
            border-radius: 5px;
            cursor: pointer;
        }

        .file-input-trigger:hover {
            background: #e9ecef;
        }

        .selected-file {
            margin-top: 10px;
            padding: 10px;
            background: #f8f9fa;
            border-radius: 5px;
            display: none;
        }

        .process-item {
            padding: 15px;
            border-bottom: 1px solid #eee;
            transition: background-color 0.2s;
        }

        .process-item:hover {
            background-color: #f8f9fa;
        }

        .process-item:last-child {
            border-bottom: none;
        }
    </style>
</head>
<body>
    <div id="loading" class="loading" style="display: none;">
        <div class="loading-spinner"></div>
    </div>

    <div class="container-fluid">
        <div class="row">
            <!-- 左侧面板 -->
            <div class="col-md-8">
                <div class="d-flex justify-content-between align-items-center mb-4">
                    <h1 class="mb-0">进程管理控制台</h1>
                    <div class="stats-card card">
                        <div class="card-body">
                            <div class="d-flex justify-content-between align-items-center">
                                <div>
                                    <p class="mb-1">监控进程数</p>
                                    <h3 id="monitoredCount">0</h3>
                                </div>
                                <i class="bi bi-cpu fs-1"></i>
                            </div>
                        </div>
                    </div>
                </div>
                
                <!-- 添加新进程表单 -->
                <div class="card">
                    <div class="card-header">
                        <h5 class="mb-0">添加新进程</h5>
                    </div>
                    <div class="card-body">
                        <form id="addProcessForm">
                            <div class="mb-3">
                                <label for="processName" class="form-label">进程名称</label>
                                <input type="text" class="form-control" id="processName" required>
                            </div>
                            <div class="mb-3">
                                <label for="processPath" class="form-label">可执行文件路径</label>
                                <div class="input-group">
                                    <input type="text" class="form-control" id="processPath" required 
                                           placeholder="请输入完整的可执行文件路径，例如：C:\Windows\notepad.exe">
                                    <button class="btn btn-outline-secondary" type="button" id="browseButton">浏览...</button>
                                </div>
                                <div class="form-text text-muted">
                                    请确保输入完整的可执行文件路径，例如：C:\\Windows\\notepad.exe
                                </div>
                            </div>
                            <button type="submit" class="btn btn-primary">添加进程</button>
                        </form>
                    </div>
                </div>
            </div>

            <!-- 右侧面板 -->
            <div class="col-md-4">
                <div class="card">
                    <div class="card-header">
                        <h5 class="card-title mb-0">已监控进程</h5>
                    </div>
                    <div class="card-body p-0">
                        <div class="monitored-processes" id="processList"></div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
    <script>
        let lastUpdateTime = 0;
        const UPDATE_INTERVAL = 5000; // 5秒更新一次
        let isUpdating = false;

        // 显示加载动画
        function showLoading() {
            document.getElementById('loading').style.display = 'flex';
        }

        // 隐藏加载动画
        function hideLoading() {
            document.getElementById('loading').style.display = 'none';
        }

        // 文件选择处理
        document.getElementById('browseButton').addEventListener('click', function() {
            const input = document.createElement('input');
            input.type = 'file';
            input.accept = '.exe';
            input.onchange = function(e) {
                const file = e.target.files[0];
                if (file) {
                    const fileName = file.name;
                    const pathInput = document.getElementById('processPath');
                    pathInput.value = fileName;
                    alert('请将文件名替换为完整的可执行文件路径，例如：C:\\Windows\\notepad.exe');
                }
            };
            input.click();
        });

        // 获取进程列表
        async function fetchProcesses(force = false) {
            const now = Date.now();
            if (!force && !isUpdating && now - lastUpdateTime < UPDATE_INTERVAL) {
                return;
            }

            if (isUpdating) {
                return;
            }

            isUpdating = true;
            showLoading();

            try {
                const response = await fetch('/api/processes');
                const processes = await response.json();
                const processList = document.getElementById('processList');
                
                // 使用DocumentFragment优化DOM操作
                const fragment = document.createDocumentFragment();
                
                processes.forEach(process => {
                    const processItem = document.createElement('div');
                    processItem.className = 'process-item';
                    processItem.innerHTML = `
                        <div class="process-name">${process.name}</div>
                        <div class="process-path">${process.command}</div>
                        <div class="process-info">
                            <span class="status ${process.status}">${process.status === 'running' ? '运行中' : '已停止'}</span>
                            <span class="ms-2">PID: ${process.pid}</span>
                        </div>
                        <div class="resource-usage">
                            <div class="usage-item">
                                <span class="usage-label">CPU:</span>
                                <span class="usage-value">${process.cpu_percent.toFixed(1)}%</span>
                            </div>
                            <div class="usage-item">
                                <span class="usage-label">内存:</span>
                                <span class="usage-value">${process.memory_percent.toFixed(1)}%</span>
                            </div>
                        </div>
                        <div class="d-flex gap-2 mt-2">
                            <button class="btn btn-stop" onclick="stopProcess('${process.name}')">
                                停止进程
                            </button>
                            <button class="btn btn-secondary" onclick="removeProcess('${process.name}')">
                                取消监控
                            </button>
                        </div>
                    `;
                    fragment.appendChild(processItem);
                });

                processList.innerHTML = '';
                processList.appendChild(fragment);
                lastUpdateTime = now;
            } catch (error) {
                console.error('Error fetching processes:', error);
            } finally {
                isUpdating = false;
                hideLoading();
            }
        }

        // 添加进程
        document.getElementById('addProcessForm').addEventListener('submit', async function(e) {
            e.preventDefault();
            const name = document.getElementById('processName').value;
            const path = document.getElementById('processPath').value;
            
            if (!name || !path) {
                alert('请填写进程名称和可执行文件路径');
                return;
            }

            if (!path.match(/^[A-Za-z]:\\.*\.exe$/i)) {
                alert('请输入正确的可执行文件路径，例如：C:\\Windows\\notepad.exe');
                return;
            }

            showLoading();
            try {
                const response = await fetch('/api/processes', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({ name, command: path })
                });

                const data = await response.json();
                if (response.ok) {
                    alert(data.message);
                    document.getElementById('addProcessForm').reset();
                    await fetchProcesses(true);
                } else {
                    alert(data.error || '添加进程失败');
                }
            } catch (error) {
                console.error('Error:', error);
                alert('添加进程失败');
            } finally {
                hideLoading();
            }
        });

        // 停止进程
        async function stopProcess(name) {
            if (!confirm(`确定要停止进程 ${name} 吗？`)) {
                return;
            }

            showLoading();
            try {
                const response = await fetch(`/api/processes/${name}`, {
                    method: 'DELETE'
                });
                const data = await response.json();
                if (response.ok) {
                    alert(data.message);
                    await fetchProcesses(true);
                } else {
                    alert(data.error || '停止进程失败');
                }
            } catch (error) {
                console.error('Error stopping process:', error);
                alert('停止进程失败');
            } finally {
                hideLoading();
            }
        }

        // 取消监控进程
        async function removeProcess(name) {
            if (!confirm(`确定要取消监控进程 ${name} 吗？`)) {
                return;
            }
            
            showLoading();
            try {
                const response = await fetch(`/api/processes/${name}/remove`, {
                    method: 'DELETE'
                });
                const data = await response.json();
                if (response.ok) {
                    alert(data.message);
                    await fetchProcesses(true);
                } else {
                    alert(data.error || '取消监控失败');
                }
            } catch (error) {
                console.error('Error removing process:', error);
                alert('取消监控失败');
            } finally {
                hideLoading();
            }
        }

        // 初始化
        document.addEventListener('DOMContentLoaded', () => {
            fetchProcesses(true);
            // 定期更新进程列表
            setInterval(() => fetchProcesses(), UPDATE_INTERVAL);
        });
    </script>
</body>
</html> 